﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LGE;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using System.IO;

namespace Stealth
{
    public class PlayScreen : GameScreen
    {
        Background bg;
        int bgOffsetY = 0;

        // Play Objects
        public Character c;
        public Map map;
        public List<Enemy> enemies = new List<Enemy>();
        public BloodBag bloodBag;
        public MapObject exitObj;

        public List<InteractiveObject> StairsUp = new List<InteractiveObject>();
        public List<InteractiveObject> StairsDown = new List<InteractiveObject>();
        public List<InteractiveObject> Doors = new List<InteractiveObject>();
        public IEnumerable<InteractiveObject> AllInteratives { get { return StairsUp.Concat(StairsDown).Concat(Doors); } }

        public Vector2 playerStartPos = Vector2.Zero;

        // XACT
        AudioCategory bgmCategory;
        AudioCategory sfxCategory;
        float bgmVolume = 1f;
        float sfxVolume = 1f;

        int Level = 0;

        public PlayScreen(int level)
            : base()
        {
            this.Level = level;
        }

        public override void LoadContent()
        {
            bg = new Background();
            Audio.PlayBGM("Level v2");
            bgmCategory = Audio.audioEngine.GetCategory("BGM");
            sfxCategory = Audio.audioEngine.GetCategory("SFX");
            bgmCategory.SetVolume(bgmVolume);
            c = new Character(this);
            LoadLevel("Levels\\" + Level + ".tmx");
        }

        public void LoadLevel(String name)
        {
            map = Map.Load(Path.Combine(Engine.game.Content.RootDirectory, name), Engine.game.Content);

            bgOffsetY = -(39 - map.Height) * 30;

            foreach (MapObject mObj in map.ObjectGroups["interactives"].Objects.Values)
            {
                InteractiveObject iObj = new InteractiveObject(this, mObj);
                if (iObj.type == InteractiveObject.UpStairs) StairsUp.Add(iObj);
                else if (iObj.type == InteractiveObject.DownStairs) StairsDown.Add(iObj);
                else if (iObj.type == InteractiveObject.Door) Doors.Add(iObj);
                else if (iObj.type == InteractiveObject.Exit) exitObj = mObj;
            }

            foreach (var obj in map.ObjectGroups["spawnpoints"].Objects.Values) //spawnpoints
            {
                if (obj.Name.Contains("medic"))
                    enemies.Add(new Medic(this, obj.Position));
                else if (obj.Name.Contains("player"))
                    playerStartPos = c.position = obj.Position;
                else if (obj.Name.Contains("blood"))
                    bloodBag = new BloodBag(this, obj.Position);
            }
        }

        public override void Update(GameTime gameTime)
        {
            if (bloodBag == null && exitObj.Bounds.Intersects(c.HitBox)) // jogador conseguiu terminar este level
            {
                Level++;
                if (Level > Stealth.Level) Stealth.Level = Level;
                GameScreenManager.ChangeScreen(new LevelSelectScreen());
            }
            bg.Update(gameTime);
            c.Update(gameTime);
            if (bloodBag != null) bloodBag.Update(gameTime);
            enemies.ForEach(e => e.Update(gameTime));

            if (Input.KeyPressed(Keys.A)) { enemies.Clear(); }
            if (Input.KeyPressed(Keys.M)) { bgmVolume = bgmVolume == 0f ? 1f : 0f; bgmCategory.SetVolume(bgmVolume); }
            if (Input.KeyPressed(Keys.N)) { sfxVolume = sfxVolume == 0f ? 1f : 0f; sfxCategory.SetVolume(sfxVolume); }
        }

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            bg.Draw(spriteBatch, new Vector2(-509, -1638 + bgOffsetY) - c.position + c.drawPosition);
            map.DrawLayer(spriteBatch, c.position - c.drawPosition, "bg");
            map.DrawLayer(spriteBatch, c.position - c.drawPosition, "props");
            foreach (InteractiveObject iObj in AllInteratives) iObj.Draw(spriteBatch);
            if (bloodBag != null) bloodBag.Draw(spriteBatch);

            if (c.isStealth)
            {
                c.Draw(spriteBatch);
                enemies.ForEach(e => e.Draw(spriteBatch));
            }
            else
            {
                enemies.ForEach(e => e.Draw(spriteBatch));
                c.Draw(spriteBatch);
            }
            
            map.DrawLayer(spriteBatch, c.position - c.drawPosition, "fg");
            //map.DrawLayer(spriteBatch, c.position - c.drawPosition, "interactive");
            //map.DrawLayer(spriteBatch, c.position - c.drawPosition, "collision");

            // HUD
            spriteBatch.DrawString(Stealth.Font, (bgmVolume == 0f ? "BGM Muted    " : "") + (sfxVolume == 0f ? "SFX Muted    " : ""), new Vector2(0, 0), Color.Red);
            if (c.interactiveObject != null)
                spriteBatch.DrawString(Stealth.Font, c.interactiveObject.name, new Vector2(0, 30), Color.White);
            spriteBatch.DrawString(Stealth.Font, "c.Pos: " + c.position.X + " | " + c.position.Y, new Vector2(0, 60), Color.White);
            spriteBatch.DrawString(Stealth.Font, "c.Speed: " + c.speed.X + " | " + c.speed.Y, new Vector2(0, 90), Color.White);
            spriteBatch.DrawString(Stealth.Font, "Enemies: " + enemies.Count, new Vector2(0, 120), Color.White);
        }

        #region Collision com TILED
        public float CollisionV(EngineObject obj, bool isUp, bool checkCodes)
        {
            return isUp ? map.CollisionUp(obj, checkCodes) : map.CollisionDown(obj, checkCodes);
        }

        public float CollisionH(EngineObject obj, bool isLeft, bool checkCodes)
        {
            return isLeft ? map.CollisionLeft(obj, checkCodes) : map.CollisionRight(obj, checkCodes);
        }
        #endregion



    }
}